﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using System.IO;
using System.Runtime.Serialization.Json;
using System.Threading;
using System.Collections;
using log4net;

namespace EmailSender
{
    public partial class Main : Form
    {
        string SenderAddress
        {
            get { return setForm.SenderAddress; }
        }
        string SmtpHost { get { return setForm.SmtpHost; } }
        string DisplayName { get { return setForm.DisplayName; } }
        string UserName { get { return setForm.UserName; } }
        string Password { get { return setForm.Password; } }
        string MailTitle { get { return setForm.MailTitle; } }
        string MailContent { get { return setForm.MailContent; } }

        SenderSet setForm = null;
        EventSet eventSetForm = null;
        int lineCount = 0;
        int sendedCount = 0;

        ILog logger;
        public Main()
        {
            InitializeComponent();
            setForm = new SenderSet();
            CheckForIllegalCrossThreadCalls = false;

            logger = LogManager.GetLogger("FilelLoger");            
        }

        private void OpenTxtFile_Click(object sender, EventArgs e)
        {
            OpenFile();          
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(setForm.MailTitle) || string.IsNullOrEmpty(setForm.MailContent))
            {
                MessageBox.Show("标题与内容不能为空");
                return;
            }
            lineCount = 0;
            sendedCount = 0;

            backgroundWorker1.RunWorkerAsync();
        }

        private void MenuItemSetSenderEmail_Click(object sender, EventArgs e)
        {
            if (null == setForm)
            {
                setForm = new SenderSet();
            }
            setForm.ShowDialog();
        }

        private void MenuItemAbout_Click(object sender, EventArgs e)
        {
            AboutBox1 form = new AboutBox1();
            form.ShowDialog();
        }

        private void btnOpenFile_Click(object sender, EventArgs e)
        {
            OpenFile();
        }

        private void OpenFile()
        {
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
            dialog.InitialDirectory = "D:\\";
            dialog.AutoUpgradeEnabled = true;
            dialog.RestoreDirectory = true;

            if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                lblFilePath.Text = dialog.FileName;
                Action action = delegate()
                {

                    using (FileStream fs = new FileStream(lblFilePath.Text, FileMode.Open, FileAccess.Read))
                    {
                        StreamReader sr = new StreamReader(fs);
                        while (sr.Peek() >= 0)
                        {
                            sr.ReadLine();
                            lineCount++;
                        }
                    }
                    lblMessage.Text = "共" + lineCount.ToString() + "行  ";
                    toolStripProgressBar1.Maximum = lineCount;
                };
                lblMessage.BeginInvoke(action);
            }
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex(@"^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$");

            btnStart.Enabled = false;
            if (string.IsNullOrEmpty(lblFilePath.Text))
                return;
            Queue<string> msgQueue = new Queue<string>(10);
            
            
            using (FileStream fs = new FileStream(lblFilePath.Text, FileMode.Open, FileAccess.Read))
            {
                StreamReader sr = new StreamReader(fs);
                while (sr.Peek() >= 0)
                {
                    if (e.Cancel)
                        return;
                    sendedCount += 1;
                    StringBuilder sb = new StringBuilder();

                    string sendTo = sr.ReadLine();
                    if (!reg.IsMatch(sendTo))
                    {
                        msgQueue.Enqueue(sendTo + "不是有效的email地址\r\n");
                        if (msgQueue.Count > 100)
                            msgQueue.Dequeue();

                        foreach (var s in msgQueue)
                        {
                            sb.Append(s);
                        }
                        txtViewSend.Text = sb.ToString();
                        lblMessage.Text = string.Format("共{0}条记录；已完成{1}条", lineCount, sendedCount);
                        toolStripProgressBar1.Value = sendedCount;
                        logger.Info("不合法:" + sendTo);
                        continue;
                    }

                    Parallel.Invoke(() =>
                    {
                        EmailWaper email = new EmailWaper(SenderAddress,DisplayName, SmtpHost, UserName, Password, 
                            sendTo, MailTitle, MailContent);
                        //事件注册
                        if (eventSetForm.EnableHttpGet)
                        {
                            email.OnSendSucess += OnHttpGetLog;
                        }
                        email.Send();
                        msgQueue.Enqueue(sendTo + "已发送\r\n");
                        if (msgQueue.Count > 100)
                            msgQueue.Dequeue();

                        foreach (var s in msgQueue)
                        {
                            sb.Append(s);
                        }

                        txtViewSend.Text = sb.ToString();
                        lblMessage.Text = string.Format("共{0}条记录；已完成{1}条", lineCount, sendedCount);
                        toolStripProgressBar1.Value = sendedCount;

                        logger.Info("已发送:" + sendTo);
                    });
                }
            }
        }

        void OnHttpGetLog(object sender, EventArgs e)
        {
            EmailWaper waper = sender as EmailWaper;
            if (null == waper)
                return;
            string url = string.Format(eventSetForm.HttpGetUri, waper.SendTo);
            try
            {
                System.Net.WebRequest request = System.Net.WebRequest.Create(url);
                request.GetResponse().Close();
            }
            catch(Exception ex)
            {
                logger.Error("HttpGet日志出错", ex);
            }
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            btnStart.Enabled = true;
        }

        private void txtViewSend_TextChanged(object sender, EventArgs e)
        {
            txtViewSend.SelectionStart= txtViewSend.Text.Length;
            txtViewSend.SelectionLength = 0;
            txtViewSend.ScrollToCaret();
        }

        private void LogEventToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (null == eventSetForm)
                eventSetForm = new EventSet();
            eventSetForm.ShowDialog();
        }

        private void Main_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (backgroundWorker1.IsBusy)
            {
                if (DialogResult.No == 
                    MessageBox.Show("任务未完成，确认要退出？", "", MessageBoxButtons.YesNo, MessageBoxIcon.Warning))
                {
                    e.Cancel = true;
                }
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            if (backgroundWorker1.IsBusy)
            {
                if (DialogResult.No ==
                    MessageBox.Show("任务未完成，确认要取消？", "", MessageBoxButtons.YesNo, MessageBoxIcon.Warning))
                {
                    backgroundWorker1.CancelAsync();
                    lineCount = 0;
                    sendedCount = 0;
                }
            }
        }
    }
}
